Original plot and data
For practice, you will try to recreate a plot published in the Economist issue of July 20th, 2016 showing the relationship between well-being and financial inclusion.
The data for the exercises EconomistData.csv can be downloaded from the class github repository.
url <- paste0("https://raw.githubusercontent.com/cme195/cme195.github.io/",
"master/assets/data/EconomistData.csv")
dat <- read.csv(url)
head(dat)
Exercise 1
- Create a scatter plot with percent of people over the age of 15 with a bank account on the x axis and the SEDA score on the y axis.
- Color the points in the previous plot blue.
- Color the points in the previous plot according to the
Region.
- Create boxplots of SEDA scores by
Region.
- Overlay points on top of the box plots
library(ggplot2)
#1. Create a scatter plot with percent of people over the age of 15 with a bank
p <- ggplot(dat, aes(x = Percent.of.15plus.with.bank.account, y = SEDA.Current.level))
p + geom_point()

#2. Color the points in the previous plot blue.
p + geom_point(color = "blue")

#3. Color the points in the previous plot according to the `Region`.
p + geom_point(aes(color = Region))

#4. Create boxplots of SEDA scores by `Region`.
boxplot <- ggplot(dat, aes(x = Region, y = SEDA.Current.level)) + geom_boxplot() +
theme(axis.text.x = element_text(angle = 15, hjust = 1))
boxplot

#5. Overlay points on top of the box plots
boxplot + geom_point()

#5. Overlay points on top of the box plots
boxplot + geom_jitter(width = 0.4)

Exercise 2
- Re-create a scatter plot with percent of people aged 15+ with a bank account on the x axis and SEDA current level score on the y axis (as you did in the previous exercise).
- Overlay a smoothing line on top of the scatter plot using the lm method. Hint: see
?geom_smooth.
- Overlay a smoothing line on top of the scatter plot using the default method.
- Overlay a smoothing line on top of the scatter plot using the default loess method, but make it less smooth. Hint: use a
span argument, for details see ?loess.
#1. Re-create a scatter plot
p <- ggplot(dat, aes(x = Percent.of.15plus.with.bank.account,
y = SEDA.Current.level))
(p <- p + geom_point())

#2. Overlay a smoothing line on top of the scatter plot using the lm method
p + geom_smooth(method = "lm")

# 3. Overlay a smoothing line on top of the scatter plot using the default method.
p + geom_smooth()

#4. Overlay a smoothing line on top of the scatter plot using the default loess
# method, but make it less smooth
p + geom_smooth(span = 0.2)

Exercise 3
- Again generate a scatter plot of % of ppl aged 15+ with bank account vs SEDA score with points colored by region, like in Exercise 1.3. But this time choose the colors of the points yourself. Hint: see
?scale_color_manual.
p <- ggplot(dat, aes(Percent.of.15plus.with.bank.account, SEDA.Current.level))
(p <- p + geom_point(aes(color = Region)) +
scale_color_manual(values = c("#33BBFF", "darkgreen", "orange","#CA33FF",
"#B2FF33", "blue", "red")))

Exercise 5
Finish the Economist plot:
- Change ordering of the regions. Hint: convert “Region” column to a factor.
- Use the seetings for the markers to best match the points on the original Economist plot. Note that the points are bigger and have white borders, and specific fill colors. The following colors match the ones on the plot:
colors <- c("#28AADC","#F2583F", "#76C0C1","#24576D", "#248E84","#DCC3AA", "#96503F")
- Add a linear trend.
- Change the axes ratio.
- Add a title and format the axes.
- Change the plot background and theme. Note that
ggthemes package has a convenient functions for generating “Economist” style plots, e.g. theme_economist_white().
- Format the legend.
- Add “Country” labels yo the points.
Change order of the Regions
dat$Region <- as.character(dat$Region)
dat$Region <- factor(dat$Region,
levels = c("Europe", "Asia", "Oceania",
"North America",
"Latin America & the Caribbean",
"Middle East & North Africa",
"Sub-Saharan Africa"),
labels = c("Europe", "Asia", "Oceania",
"North America",
"Latin America & \n the Caribbean",
"Middle East & \n North Africa",
"Sub-Saharan \n Africa"))
ggplot(dat, aes(Percent.of.15plus.with.bank.account, SEDA.Current.level)) +
geom_point(aes(color = Region))

Change the color scheme
colors <- c("#28AADC","#F2583F", "#76C0C1","#24576D", "#248E84","#DCC3AA", "#96503F")
ggplot(dat, aes(Percent.of.15plus.with.bank.account, SEDA.Current.level)) +
geom_point(aes(fill = Region), color = "white", size = 4, pch = 21) +
scale_fill_manual(name = "", values = colors)

Add the linear trend
p <- ggplot(dat, aes(Percent.of.15plus.with.bank.account, SEDA.Current.level)) +
geom_smooth(method = "lm", se = FALSE, col = "black", size = 0.5) +
geom_point(aes(fill = Region), color = "white", size = 4, pch = 21) +
scale_fill_manual(name = "", values = colors)
p

Change the axes ratio.
(p <- p + coord_fixed(ratio = 0.4))

Change the background and theme
You can check out the ggthemes package which implement the themes that make your plots look like they came from:
- Base graphics
- Tableau
- Excel
- Stata
- Economist
- Wall Street Journal
- Edward Tufte
- Nate Silver’s Fivethirtyeight
- etc.
#install.packages("ggthemes")
library(ggthemes)
(p <- p + theme_economist_white(gray_bg = FALSE))

Add point labels
pointsToLabel <- c("Yemen", "Iraq", "Egypt", "Jordan", "Chad", "Congo",
"Angola", "Albania", "Zimbabwe", "Uganda", "Nigeria",
"Uruguay", "Kazakhstan", "India", "Turkey", "South Africa",
"Kenya", "Russia", "Brazil", "Chile", "Saudi Arabia",
"Poland", "China", "Serbia", "United States", "United Kingdom")
# install.packages("ggrepel")
library(dplyr); library(ggrepel)
(p <- p +
geom_text_repel(aes(label = Country), color = "grey20",
data = dat %>% filter(Country %in% pointsToLabel),
force = 15))

Add notes to the bottom and save the plot
Use “grid.text()” to add notes
library(grid)
png(file = "./econScatter.png", width = 750, height = 400)
p
grid.text("Source: Boston Consulting Group",
x = 0.02, y = 0.02, just = "left",
gp = gpar(fontsize = 10, col="grey37"))
grid.text("*Data available for 123 countries \n Sustainable economic development assesment",
x = 0.92, y = .05, just = "right",
gp = gpar(fontsize = 10, col = "grey37"))
dev.off()
null device
1
Similar to the original:
LS0tCnRpdGxlOiAiTGVjdHVyZSA0OiBFeGVyY2lzZXMgd2l0aCBhbnN3ZXJzIgpkYXRlOiBPY3RvYmVyIDEydGgsIDIwMTcKb3V0cHV0OiAKICBodG1sX25vdGVib29rOgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKLS0tCgojIE9yaWdpbmFsIHBsb3QgYW5kIGRhdGEKCkZvciBwcmFjdGljZSwgeW91IHdpbGwgdHJ5IHRvIHJlY3JlYXRlCmEgcGxvdCBwdWJsaXNoZWQgaW4gdGhlIEVjb25vbWlzdCBpc3N1ZSBvZiBKdWx5IDIwdGgsIDIwMTYgc2hvd2luZwp0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gd2VsbC1iZWluZyBhbmQgZmluYW5jaWFsIGluY2x1c2lvbi4KCiFbXSguLi9kYXRhL2Vjb25vbWlzdC5wbmcpCgoqIFRoZSBvcmlnaW5hbCBncmFwaCB3YXMgdGFrZW4gZnJvbSB0aGlzIApbYXJ0aWNsZV0oaHR0cDovL3d3dy5lY29ub21pc3QuY29tL2Jsb2dzL2dyYXBoaWNkZXRhaWwvMjAxNi8wNy9kYWlseS1jaGFydC0xMykKCiogWW91IHdpbGwgZ2VuZXJhdGUgdGhpcyBmaWd1cmUgc3RlcCBieSBzdGVwIHRocm91Z2ggYSBzZXJpZXMgb2YgaW5jbHVkZWQgCmV4ZXJjaXNlcyB1c2luZyB0aGUgdG9vbHMgd2UndmUganVzdCBsZWFybmVkIGFuZCB3aWxsIGxlYXJuIGFib3V0LiAKCgpUaGUgZGF0YSBmb3IgdGhlIGV4ZXJjaXNlcyBgRWNvbm9taXN0RGF0YS5jc3ZgIGNhbiBiZSBkb3dubG9hZGVkIGZyb20gCnRoZSBjbGFzcyBnaXRodWIgcmVwb3NpdG9yeS4KCmBgYHtyfQp1cmwgPC0gcGFzdGUwKCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vY21lMTk1L2NtZTE5NS5naXRodWIuaW8vIiwKICAgICAgICAgICAgICAibWFzdGVyL2Fzc2V0cy9kYXRhL0Vjb25vbWlzdERhdGEuY3N2IikKZGF0IDwtIHJlYWQuY3N2KHVybCkKaGVhZChkYXQpCmBgYAoKCiMgRXhlcmNpc2UgMQoKMS4gQ3JlYXRlIGEgc2NhdHRlciBwbG90IHdpdGggcGVyY2VudCBvZiBwZW9wbGUgb3ZlciB0aGUgYWdlCm9mIDE1IHdpdGggYSBiYW5rIGFjY291bnQgb24gdGhlIHggYXhpcyBhbmQgdGhlIFNFREEgc2NvcmUgb24gdGhlIHkgYXhpcy4KMi4gQ29sb3IgdGhlIHBvaW50cyBpbiB0aGUgcHJldmlvdXMgcGxvdCBibHVlLgozLiBDb2xvciB0aGUgcG9pbnRzIGluIHRoZSBwcmV2aW91cyBwbG90IGFjY29yZGluZyB0byB0aGUgYFJlZ2lvbmAuCjQuIENyZWF0ZSBib3hwbG90cyBvZiBTRURBIHNjb3JlcyBieSBgUmVnaW9uYC4KNS4gT3ZlcmxheSBwb2ludHMgb24gdG9wIG9mIHRoZSBib3ggcGxvdHMKCgpgYGB7cn0KbGlicmFyeShnZ3Bsb3QyKQojMS4gQ3JlYXRlIGEgc2NhdHRlciBwbG90IHdpdGggcGVyY2VudCBvZiBwZW9wbGUgb3ZlciB0aGUgYWdlIG9mIDE1IHdpdGggYSBiYW5rIApwIDwtIGdncGxvdChkYXQsIGFlcyh4ID0gUGVyY2VudC5vZi4xNXBsdXMud2l0aC5iYW5rLmFjY291bnQsIHkgPSBTRURBLkN1cnJlbnQubGV2ZWwpKSAKcCArIGdlb21fcG9pbnQoKQpgYGAKCmBgYHtyfQojMi4gQ29sb3IgdGhlIHBvaW50cyBpbiB0aGUgcHJldmlvdXMgcGxvdCBibHVlLgpwICsgZ2VvbV9wb2ludChjb2xvciA9ICJibHVlIikKYGBgCgpgYGB7cn0KIzMuIENvbG9yIHRoZSBwb2ludHMgaW4gdGhlIHByZXZpb3VzIHBsb3QgYWNjb3JkaW5nIHRvIHRoZSBgUmVnaW9uYC4KcCArIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gUmVnaW9uKSkKYGBgCgpgYGB7cn0KIzQuIENyZWF0ZSBib3hwbG90cyBvZiBTRURBIHNjb3JlcyBieSBgUmVnaW9uYC4KYm94cGxvdCA8LSBnZ3Bsb3QoZGF0LCBhZXMoeCA9IFJlZ2lvbiwgeSA9IFNFREEuQ3VycmVudC5sZXZlbCkpICsgZ2VvbV9ib3hwbG90KCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMTUsIGhqdXN0ID0gMSkpCmJveHBsb3QKYGBgCgpgYGB7cn0KIzUuIE92ZXJsYXkgcG9pbnRzIG9uIHRvcCBvZiB0aGUgYm94IHBsb3RzCmJveHBsb3QgKyBnZW9tX3BvaW50KCkKYGBgCgpgYGB7cn0KIzUuIE92ZXJsYXkgcG9pbnRzIG9uIHRvcCBvZiB0aGUgYm94IHBsb3RzCmJveHBsb3QgKyBnZW9tX2ppdHRlcih3aWR0aCA9IDAuNCkKYGBgCgoKIyBFeGVyY2lzZSAyCgoxLiBSZS1jcmVhdGUgYSBzY2F0dGVyIHBsb3Qgd2l0aCBwZXJjZW50IG9mIHBlb3BsZSBhZ2VkIDE1KyB3aXRoIGEgYmFuayBhY2NvdW50Cm9uIHRoZSB4IGF4aXMgYW5kIFNFREEgY3VycmVudCBsZXZlbCBzY29yZSBvbiB0aGUgeSBheGlzIAooYXMgeW91IGRpZCBpbiB0aGUgcHJldmlvdXMgZXhlcmNpc2UpLgoyLiBPdmVybGF5IGEgc21vb3RoaW5nIGxpbmUgb24gdG9wIG9mIHRoZSBzY2F0dGVyIHBsb3QgdXNpbmcgdGhlIGxtIG1ldGhvZC4gCkhpbnQ6IHNlZSBgP2dlb21fc21vb3RoYC4KMy4gT3ZlcmxheSBhIHNtb290aGluZyBsaW5lIG9uIHRvcCBvZiB0aGUgc2NhdHRlciBwbG90IHVzaW5nIHRoZSBkZWZhdWx0IG1ldGhvZC4KNC4gT3ZlcmxheSBhIHNtb290aGluZyBsaW5lIG9uIHRvcCBvZiB0aGUgc2NhdHRlciBwbG90IHVzaW5nIHRoZSBkZWZhdWx0IGxvZXNzIAptZXRob2QsIGJ1dCBtYWtlIGl0IGxlc3Mgc21vb3RoLiBIaW50OiB1c2UgYSBgc3BhbmAgYXJndW1lbnQsIGZvciBkZXRhaWxzIHNlZSBgP2xvZXNzYC4KCmBgYHtyfQojMS4gUmUtY3JlYXRlIGEgc2NhdHRlciBwbG90CnAgPC0gZ2dwbG90KGRhdCwgYWVzKHggPSBQZXJjZW50Lm9mLjE1cGx1cy53aXRoLmJhbmsuYWNjb3VudCwgCiAgICAgICAgICAgICAgICAgICAgIHkgPSBTRURBLkN1cnJlbnQubGV2ZWwpKQoocCA8LSBwICsgZ2VvbV9wb2ludCgpKQpgYGAKCmBgYHtyfQojMi4gT3ZlcmxheSBhIHNtb290aGluZyBsaW5lIG9uIHRvcCBvZiB0aGUgc2NhdHRlciBwbG90IHVzaW5nIHRoZSBsbSBtZXRob2QKcCArIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIpCmBgYAoKYGBge3J9CiMgMy4gT3ZlcmxheSBhIHNtb290aGluZyBsaW5lIG9uIHRvcCBvZiB0aGUgc2NhdHRlciBwbG90IHVzaW5nIHRoZSBkZWZhdWx0IG1ldGhvZC4KcCArIGdlb21fc21vb3RoKCkKYGBgCgpgYGB7cn0KIzQuIE92ZXJsYXkgYSBzbW9vdGhpbmcgbGluZSBvbiB0b3Agb2YgdGhlIHNjYXR0ZXIgcGxvdCB1c2luZyB0aGUgZGVmYXVsdCBsb2VzcyAKIyBtZXRob2QsIGJ1dCBtYWtlIGl0IGxlc3Mgc21vb3RoCnAgKyBnZW9tX3Ntb290aChzcGFuID0gMC4yKQpgYGAKCgojIEV4ZXJjaXNlIDMKCjEuIEFnYWluIGdlbmVyYXRlIGEgc2NhdHRlciBwbG90IG9mICUgb2YgcHBsIGFnZWQgMTUrIHdpdGggYmFuayBhY2NvdW50IAp2cyBTRURBIHNjb3JlIHdpdGggcG9pbnRzIGNvbG9yZWQgYnkgcmVnaW9uLCBsaWtlIGluIEV4ZXJjaXNlIDEuMy4KQnV0IHRoaXMgdGltZSBjaG9vc2UgdGhlIGNvbG9ycyBvZiB0aGUgcG9pbnRzIHlvdXJzZWxmLgpIaW50OiBzZWUgYD9zY2FsZV9jb2xvcl9tYW51YWxgLgoKYGBge3J9CnAgPC0gZ2dwbG90KGRhdCwgYWVzKFBlcmNlbnQub2YuMTVwbHVzLndpdGguYmFuay5hY2NvdW50LCBTRURBLkN1cnJlbnQubGV2ZWwpKSAKKHAgPC0gcCArIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gUmVnaW9uKSkgKyAKICAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCIjMzNCQkZGIiwgImRhcmtncmVlbiIsICJvcmFuZ2UiLCIjQ0EzM0ZGIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiI0IyRkYzMyIsICJibHVlIiwgInJlZCIpKSkKYGBgCgojIEV4ZXJjaXNlIDQKCjEuIEZhY2V0ICBieSByZWdpb24gKGB+IFJlZ2lvbmApIHRoZSB0aGUgRWNvbm9taXN0IHBsb3QgZnJvbSBFeGVyY2lzZSAzLgoKYGBge3J9CnAgKyBmYWNldF93cmFwKH4gUmVnaW9uKQpgYGAKCgoKIyBFeGVyY2lzZSA1CgpGaW5pc2ggdGhlIEVjb25vbWlzdCBwbG90OgoKMS4gQ2hhbmdlIG9yZGVyaW5nIG9mIHRoZSByZWdpb25zLiBIaW50OiBjb252ZXJ0ICJSZWdpb24iIGNvbHVtbiB0byBhIGZhY3Rvci4KMi4gVXNlIHRoZSBzZWV0aW5ncyBmb3IgdGhlIG1hcmtlcnMgdG8gYmVzdCBtYXRjaCB0aGUgcG9pbnRzIG9uIHRoZSBvcmlnaW5hbCAKRWNvbm9taXN0IHBsb3QuIE5vdGUgdGhhdCB0aGUgcG9pbnRzIGFyZSBiaWdnZXIgYW5kIGhhdmUgd2hpdGUgYm9yZGVycywKYW5kIHNwZWNpZmljIGZpbGwgY29sb3JzLiBUaGUgZm9sbG93aW5nIGNvbG9ycyBtYXRjaCB0aGUgb25lcyBvbiB0aGUgcGxvdDoKYGNvbG9ycyA8LSAgYygiIzI4QUFEQyIsIiNGMjU4M0YiLCAiIzc2QzBDMSIsIiMyNDU3NkQiLCAiIzI0OEU4NCIsIiNEQ0MzQUEiLCAiIzk2NTAzRiIpYAozLiBBZGQgYSBsaW5lYXIgdHJlbmQuCjQuIENoYW5nZSB0aGUgYXhlcyByYXRpby4KNS4gQWRkIGEgdGl0bGUgYW5kIGZvcm1hdCB0aGUgYXhlcy4KNi4gQ2hhbmdlIHRoZSBwbG90IGJhY2tncm91bmQgYW5kIHRoZW1lLiBOb3RlIHRoYXQgYGdndGhlbWVzYCBwYWNrYWdlCmhhcyBhIGNvbnZlbmllbnQgZnVuY3Rpb25zIGZvciBnZW5lcmF0aW5nICJFY29ub21pc3QiIHN0eWxlIHBsb3RzLCAKZS5nLiBgdGhlbWVfZWNvbm9taXN0X3doaXRlKClgLgo3LiBGb3JtYXQgdGhlIGxlZ2VuZC4KOC4gQWRkICJDb3VudHJ5IiBsYWJlbHMgeW8gdGhlIHBvaW50cy4KCgojIyMgQ2hhbmdlIG9yZGVyIG9mIHRoZSBSZWdpb25zCgpgYGB7cn0KZGF0JFJlZ2lvbiA8LSBhcy5jaGFyYWN0ZXIoZGF0JFJlZ2lvbikKZGF0JFJlZ2lvbiA8LSBmYWN0b3IoZGF0JFJlZ2lvbiwgCiAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIkV1cm9wZSIsICJBc2lhIiwgIk9jZWFuaWEiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTm9ydGggQW1lcmljYSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJMYXRpbiBBbWVyaWNhICYgdGhlIENhcmliYmVhbiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNaWRkbGUgRWFzdCAmIE5vcnRoIEFmcmljYSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlN1Yi1TYWhhcmFuIEFmcmljYSIpLAogICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJFdXJvcGUiLCAiQXNpYSIsICJPY2VhbmlhIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5vcnRoIEFtZXJpY2EiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTGF0aW4gQW1lcmljYSAmIFxuIHRoZSBDYXJpYmJlYW4iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWlkZGxlIEVhc3QgJiBcbiBOb3J0aCBBZnJpY2EiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTdWItU2FoYXJhbiBcbiBBZnJpY2EiKSkKYGBgCgoKYGBge3J9CmdncGxvdChkYXQsIGFlcyhQZXJjZW50Lm9mLjE1cGx1cy53aXRoLmJhbmsuYWNjb3VudCwgU0VEQS5DdXJyZW50LmxldmVsKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvciA9IFJlZ2lvbikpCmBgYAoKIyMjIENoYW5nZSB0aGUgY29sb3Igc2NoZW1lCgpgYGB7cn0KY29sb3JzIDwtICBjKCIjMjhBQURDIiwiI0YyNTgzRiIsICIjNzZDMEMxIiwiIzI0NTc2RCIsICIjMjQ4RTg0IiwiI0RDQzNBQSIsICIjOTY1MDNGIikKZ2dwbG90KGRhdCwgYWVzKFBlcmNlbnQub2YuMTVwbHVzLndpdGguYmFuay5hY2NvdW50LCBTRURBLkN1cnJlbnQubGV2ZWwpKSArIAogICAgZ2VvbV9wb2ludChhZXMoZmlsbCA9IFJlZ2lvbiksIGNvbG9yID0gIndoaXRlIiwgc2l6ZSA9IDQsIHBjaCA9IDIxKSArCiAgICBzY2FsZV9maWxsX21hbnVhbChuYW1lID0gIiIsIHZhbHVlcyA9IGNvbG9ycykKYGBgCgoKIyMjIEFkZCB0aGUgbGluZWFyIHRyZW5kCgpgYGB7cn0KcCA8LSBnZ3Bsb3QoZGF0LCBhZXMoUGVyY2VudC5vZi4xNXBsdXMud2l0aC5iYW5rLmFjY291bnQsIFNFREEuQ3VycmVudC5sZXZlbCkpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGQUxTRSwgY29sID0gImJsYWNrIiwgc2l6ZSA9IDAuNSkgKwogIGdlb21fcG9pbnQoYWVzKGZpbGwgPSBSZWdpb24pLCBjb2xvciA9ICJ3aGl0ZSIsIHNpemUgPSA0LCBwY2ggPSAyMSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKG5hbWUgPSAiIiwgdmFsdWVzID0gY29sb3JzKQpwCmBgYAoKIyMjIENoYW5nZSB0aGUgYXhlcyByYXRpby4KCmBgYHtyfQoocCA8LSBwICsgY29vcmRfZml4ZWQocmF0aW8gPSAwLjQpKQpgYGAKCgojIyMgQWRkIGEgdGl0bGUgYW5kIGZvcm1hdCB0aGUgYXhlcwoKYGBge3J9CihwIDwtIHAgKwogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIiUgb2YgcGVvcGxlIGFnZWQgMTUrIHdpdGggYmFuayBhY2NvdW50LCAyMDE0IiwKICAgICAgICAgICAgICAgICAgICAgbGltaXRzID0gYygwLCAxMDApLAogICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBzZXEoMCwgMTAwLCBieSA9IDIwKSkgKwogIHNjYWxlX3lfY29udGludW91cyhuYW1lID0gIlNFREEgU2NvcmUsIDEwMD1tYXhpbXVtIiwKICAgICAgICAgICAgICAgICAgICAgbGltaXRzID0gYygwLCAxMDApLAogICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBzZXEoMCwgMTAwLCBieSA9IDIwKSkgKwogICBsYWJzKHRpdGxlPSJMYXVnaGluZyBhbGwgdGhlIHdheSB0byB0aGUgYmFuayIsCiAgICAgICAgc3VidGl0bGU9IldlbGwtYmVpbmcgYW5kIGZpbmFuY2lhbCBpbmNsdXNpb24qIFxuIDIwMTQtMTUiKSkKYGBgCgojIyMgQ2hhbmdlIHRoZSBiYWNrZ3JvdW5kIGFuZCB0aGVtZQoKWW91IGNhbiBjaGVjayBvdXQgdGhlIFtgZ2d0aGVtZXNgXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvZ2d0aGVtZXMvdmlnbmV0dGVzL2dndGhlbWVzLmh0bWwpIApwYWNrYWdlIHdoaWNoIGltcGxlbWVudCB0aGUgdGhlbWVzIHRoYXQgbWFrZSB5b3VyIHBsb3RzIGxvb2sgbGlrZSB0aGV5IGNhbWUgZnJvbToKCiogQmFzZSBncmFwaGljcwoqIFRhYmxlYXUKKiBFeGNlbAoqIFN0YXRhCiogRWNvbm9taXN0CiogV2FsbCBTdHJlZXQgSm91cm5hbAoqIEVkd2FyZCBUdWZ0ZQoqIE5hdGUgU2lsdmVyJ3MgRml2ZXRoaXJ0eWVpZ2h0CiogZXRjLgoKYGBge3J9CiNpbnN0YWxsLnBhY2thZ2VzKCJnZ3RoZW1lcyIpCmxpYnJhcnkoZ2d0aGVtZXMpCihwIDwtIHAgKyB0aGVtZV9lY29ub21pc3Rfd2hpdGUoZ3JheV9iZyA9IEZBTFNFKSkKYGBgCgojIyMgRm9ybWF0IHRoZSBsZWdlbmQKCmBgYHtyLCBmaWcud2lkdGg9OSwgZmlnLmhlaWdodD01fQoocCA8LSBwICsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJncmV5MzUiLCBzaXplID0gMTEpLAogICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgICAgICBsZWdlbmQucG9zaXRpb24gPSBjKDAuNzIsIDEuMTIpLCAgIAogICAgICAgICBsZWdlbmQuZGlyZWN0aW9uID0gImhvcml6b250YWwiLAogICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSByZWwoMS4yKSwgY29sb3IgPSAiYmxhY2siKSwKICAgICAgICAgcGxvdC5tYXJnaW4gPSB1bml0KGMoMSwgMS41LCAxLjUsIDAuNSksICJjbSIpKSArCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQobmNvbCA9IDQsIGJ5cm93ID0gRkFMU0UpKSkKYGBgCgojIyMgQWRkIHBvaW50IGxhYmVscwoKYGBge3J9CnBvaW50c1RvTGFiZWwgPC0gYygiWWVtZW4iLCAiSXJhcSIsICJFZ3lwdCIsICJKb3JkYW4iLCAiQ2hhZCIsICJDb25nbyIsIAogICAgICAgICAgICAgICAgICAgIkFuZ29sYSIsICJBbGJhbmlhIiwgIlppbWJhYndlIiwgIlVnYW5kYSIsICJOaWdlcmlhIiwKICAgICAgICAgICAgICAgICAgICJVcnVndWF5IiwgIkthemFraHN0YW4iLCAiSW5kaWEiLCAiVHVya2V5IiwgIlNvdXRoIEFmcmljYSIsCiAgICAgICAgICAgICAgICAgICAiS2VueWEiLCAiUnVzc2lhIiwgIkJyYXppbCIsICJDaGlsZSIsICJTYXVkaSBBcmFiaWEiLCAKICAgICAgICAgICAgICAgICAgICJQb2xhbmQiLCAiQ2hpbmEiLCAiU2VyYmlhIiwgIlVuaXRlZCBTdGF0ZXMiLCAiVW5pdGVkIEtpbmdkb20iKQpgYGAKCmBgYHtyLCBmaWcud2lkdGg9OSwgZmlnLmhlaWdodD01fQojIGluc3RhbGwucGFja2FnZXMoImdncmVwZWwiKQpsaWJyYXJ5KGRwbHlyKTsgbGlicmFyeShnZ3JlcGVsKQoocCA8LSAgcCArIAogICAgZ2VvbV90ZXh0X3JlcGVsKGFlcyhsYWJlbCA9IENvdW50cnkpLCBjb2xvciA9ICJncmV5MjAiLAogICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF0ICU+JSBmaWx0ZXIoQ291bnRyeSAlaW4lIHBvaW50c1RvTGFiZWwpLAogICAgICAgICAgICAgICAgICAgICAgICBmb3JjZSA9IDE1KSkKYGBgCgojIyMgQWRkIG5vdGVzIHRvIHRoZSBib3R0b20gYW5kIHNhdmUgdGhlIHBsb3QKClVzZSAiZ3JpZC50ZXh0KCkiIHRvIGFkZCBub3RlcwoKYGBge3J9CmxpYnJhcnkoZ3JpZCkKcG5nKGZpbGUgPSAiLi4vZGF0YS9lY29uU2NhdHRlci5wbmciLCB3aWR0aCA9IDc1MCwgaGVpZ2h0ID0gNDAwKQpwCmdyaWQudGV4dCgiU291cmNlOiBCb3N0b24gQ29uc3VsdGluZyBHcm91cCIsCiAgICAgICAgICB4ID0gMC4wMiwgeSA9IDAuMDIsIGp1c3QgPSAibGVmdCIsCiAgICAgICAgICBncCA9IGdwYXIoZm9udHNpemUgPSAxMCwgY29sPSJncmV5MzciKSkKZ3JpZC50ZXh0KCIqRGF0YSBhdmFpbGFibGUgZm9yIDEyMyBjb3VudHJpZXMgXG4gU3VzdGFpbmFibGUgZWNvbm9taWMgZGV2ZWxvcG1lbnQgYXNzZXNtZW50IiwKICAgICAgICAgIHggPSAwLjkyLCB5ID0gLjA1LCBqdXN0ID0gInJpZ2h0IiwKICAgICAgICAgIGdwID0gZ3Bhcihmb250c2l6ZSA9IDEwLCBjb2wgPSAiZ3JleTM3IikpCmRldi5vZmYoKQpgYGAKCgohW10oLi4vZGF0YS9lY29uU2NhdHRlci5wbmcpCgoKU2ltaWxhciB0byB0aGUgb3JpZ2luYWw6CgohW10oLi4vZGF0YS9lY29ub21pc3QucG5nKQo=